package io.yuanqi.hgtcshop.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.org.apache.xpath.internal.operations.Or;
import io.yuanqi.hgtcshop.config.RedisService;
import io.yuanqi.hgtcshop.dao.OrderMapper;
import io.yuanqi.hgtcshop.entity.dos.*;
import io.yuanqi.hgtcshop.entity.enums.DeliverStatusEnum;
import io.yuanqi.hgtcshop.entity.enums.OrderStatusEnum;
import io.yuanqi.hgtcshop.entity.enums.OrderTypeEnum;
import io.yuanqi.hgtcshop.entity.enums.PayStatusEnum;
import io.yuanqi.hgtcshop.entity.vo.OrderVO;
import io.yuanqi.hgtcshop.entity.vo.TimeVO;
import io.yuanqi.hgtcshop.entity.vo.UserNameAndFaceVO;
import io.yuanqi.hgtcshop.service.*;
import io.yuanqi.hgtcshop.utils.CountdownTimer;
import io.yuanqi.hgtcshop.utils.LocalDateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 子订单业务层实现
 *
 * @author Chopper
 * @since 2020/11/17 7:38 下午
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private static final String ORDER_SN_COLUMN = "order_sn";
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private MemberAddressService memberAddressService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private GoodsSkuService goodsSkuService;
    @Autowired
    private RedisService redisService;

    @Override
    public String createOrderTrade(String openId, String[] skuIds) {
        String orderSn = "order_" + LocalDateUtils.getStr();
        // 创建订单明细
        Double totalPrice = createOrderDetail(skuIds, openId, orderSn);
        // 创建总订单
        createOrder(openId, skuIds, orderSn, totalPrice);
        // 删除购物车
        redisService.deleteKey("CART_" + openId);
        // 销毁
        String key = "check_" + openId;
        redisService.deleteKey(key);
        // 返回订单
        return orderSn;
    }

    private CountdownTimer timer = new CountdownTimer();

    @Override
    public OrderVO getOrderBySn(String orderSn) {
//        OrderVO orderVO = new OrderVO();
//        List<OrderItem> byOrderSn = orderItemService.getByOrderSn(orderSn);
//        orderVO.setOrderItems(byOrderSn);
//
//        LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
//        lambdaQueryWrapper.eq(Order::getSn, orderSn);
//        Order order = orderMapper.selectOne(lambdaQueryWrapper);
//        if (null != order) {
//            orderVO.setTotalPrice(order.getFlowPrice());
//        }
//        orderVO.setGoodNum(byOrderSn.size());
//        return orderVO;

        OrderVO orderVO = new OrderVO();
        List<OrderItem> byOrderSn = orderItemService.getByOrderSn(orderSn);
        orderVO.setOrderItems(byOrderSn);

        LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Order::getSn, orderSn);
        Order order = orderMapper.selectOne(lambdaQueryWrapper);
        if (null != order) {
            orderVO.setTotalPrice(order.getFlowPrice());
        }
        orderVO.setGoodNum(byOrderSn.size());
        Long time = timer.getTime(orderSn);
        TimeVO timeVO;
        if (null == time) {
            long startTime = System.currentTimeMillis();
            long endTime = startTime + TimeUnit.SECONDS.toMillis(900); // 900 秒为 15 分钟
            timer.putTime(orderSn, endTime);
            orderVO.setSecond(599L);

        } else {
            long currentCountdownTime = timer.getCurrentCountdownTime(orderSn);
            orderVO.setSecond(currentCountdownTime);
        }

        return orderVO;
    }

    @Override
    public List<OrderVO> getOrderByMemberId(String memberId, Integer orderType) {
        ArrayList<OrderVO> orderVOS = new ArrayList<>();

        MemberAddress defaultMemberAddress = memberAddressService.getDefaultMemberAddress(memberId);

        if (orderType.equals(0)) {
            LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(Order::getMemberId, memberId);
            lambdaQueryWrapper.eq(Order::getPayStatus, PayStatusEnum.UNPAID.name());
            List<Order> orders = orderMapper.selectList(lambdaQueryWrapper);
            for (Order order : orders) {
                OrderVO orderVO = new OrderVO();
                orderVO.setOrderSn(order.getSn());
                List<OrderItem> byOrderSn = orderItemService.getByOrderSn(order.getSn());
                orderVO.setOrderItems(byOrderSn);
                orderVO.setTotalPrice(order.getFlowPrice());
                orderVO.setGoodNum(byOrderSn.size());
                orderVO.setPayStatus(order.getPayStatus());
                orderVO.setMemberAddress(defaultMemberAddress);
                orderVOS.add(orderVO);
            }
            return orderVOS;
        } else if (orderType.equals(1)) {
            LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(Order::getMemberId, memberId) // memberId = 1
                    .and(wrapper -> wrapper
                            .eq(Order::getPayStatus, PayStatusEnum.PAID) // getPayStatus = 2
                            .or()
                            .eq(Order::getPayStatus, PayStatusEnum.CANCEL)); // o
            List<Order> orders = orderMapper.selectList(lambdaQueryWrapper);
            for (Order order : orders) {
                OrderVO orderVO = new OrderVO();
                orderVO.setOrderSn(order.getSn());
                List<OrderItem> byOrderSn = orderItemService.getByOrderSn(order.getSn());
                orderVO.setOrderItems(byOrderSn);
                orderVO.setTotalPrice(order.getFlowPrice());
                orderVO.setGoodNum(byOrderSn.size());
                orderVO.setPayStatus(order.getPayStatus());
                orderVO.setMemberAddress(defaultMemberAddress);
                orderVOS.add(orderVO);
            }
            return orderVOS;
        } else {
            LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(Order::getMemberId, memberId);
            List<Order> orders = orderMapper.selectList(lambdaQueryWrapper);
            for (Order order : orders) {
                OrderVO orderVO = new OrderVO();
                orderVO.setOrderSn(order.getSn());
                List<OrderItem> byOrderSn = orderItemService.getByOrderSn(order.getSn());
                orderVO.setOrderItems(byOrderSn);
                orderVO.setTotalPrice(order.getFlowPrice());
                orderVO.setGoodNum(byOrderSn.size());
                orderVO.setPayStatus(order.getPayStatus());
                orderVO.setMemberAddress(defaultMemberAddress);
                orderVOS.add(orderVO);
            }
            return orderVOS;
        }
    }

    @Override
    public UserNameAndFaceVO getUserNameAndFaceByOrderSn(String orderSn) {
        LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Order::getSn, orderSn);
        Order order = orderMapper.selectOne(lambdaQueryWrapper);
        String memberId = order.getMemberId();
        Member member = memberService.findByMemberId(memberId);

        UserNameAndFaceVO userNameAndFaceVO = new UserNameAndFaceVO();
        if (member!= null && member.getNickName()!=null){
            userNameAndFaceVO.setNickname(member.getNickName());
        }
        if (member!=null && member.getFace() != null){
            userNameAndFaceVO.setHeadimgurl(member.getFace());
        }
        if (member!=null && member.getUsername()!=null){
            userNameAndFaceVO.setOpenId(member.getUsername());
        }
        return userNameAndFaceVO;
    }

    @Override
    public Order getOrder(String orderSn) {
        LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Order::getSn, orderSn);
        Order order = orderMapper.selectOne(lambdaQueryWrapper);
        return order;
    }

    @Override
    public Boolean updatePayOrderSnByOrderSn(String orderSn, String payOrderSn) {
        LambdaUpdateWrapper<Order> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        lambdaUpdateWrapper.set(Order::getPayOrderNo, payOrderSn);
        lambdaUpdateWrapper.set(Order::getUpdateTime, new Date());
        lambdaUpdateWrapper.eq(Order::getSn, orderSn);
        return this.update(lambdaUpdateWrapper);
    }

    @Override
    public Boolean updatePayStatusByOrderSn(String orderSn, String tradeNo, Date successDate, PayStatusEnum payStatusEnum) {
        LambdaUpdateWrapper<Order> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
        lambdaUpdateWrapper.set(Order::getPayStatus, payStatusEnum.PAID.name());
        lambdaUpdateWrapper.set(Order::getTradeSn, tradeNo);
        lambdaUpdateWrapper.set(Order::getUpdateTime, successDate);
        lambdaUpdateWrapper.eq(Order::getSn, orderSn);
        return this.update(lambdaUpdateWrapper);
    }

    @Override
    public Order getOrderInfo(String orderSn) {
        LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Order::getSn, orderSn);
        Order order = orderMapper.selectOne(lambdaQueryWrapper);
        return order;
    }

    @Override
    public Boolean updateAddress(String orderSn,String openId) {

        // 获取订单
        LambdaQueryWrapper<Order> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Order::getSn, orderSn);
        Order order = orderMapper.selectOne(lambdaQueryWrapper);

        // 物流相关的信息
        MemberAddress memberAddress = memberAddressService.getDefaultMemberAddress(openId);
        if (memberAddress != null) {
            order.setConsigneeAddressIdPath(memberAddress.getConsigneeAddressIdPath());
            order.setConsigneeAddressPath(memberAddress.getConsigneeAddressPath());
            order.setConsigneeDetail(memberAddress.getDetail());
            order.setConsigneeMobile(memberAddress.getMobile());
            order.setConsigneeName(memberAddress.getName());
            order.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
            order.setUpdateTime(new Date());
            orderMapper.updateById(order);
            log.info(".updateAddress 修改地址完成");
            return true;
        }
        log.info(".updateAddress 修改地址失败");
        return false;
    }

    /**
     * 价格用sku里面的price
     * 图片用original
     */
    private Double createOrderDetail(String[] skuIds, String openId, String orderSn) {

        List<String> skuIdList = Arrays.asList(skuIds);
        ArrayList<OrderItem> orderItems = new ArrayList<>();
        Double totalPrice = new Double(0);

        for (String skuId : skuIdList) {
            GoodsSku skuBySkuId = goodsSkuService.getSkuBySkuId(skuId);
            if (null == skuBySkuId) {
                log.error("SkuId 不存在:{}", skuId);
                throw new RuntimeException("SkuId 不存在:" + skuId);
            }
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderSn(orderSn);
            orderItem.setDeleteFlag(false);
            orderItem.setCreateTime(new Date());
            orderItem.setUpdateTime(new Date());
            orderItem.setCreateBy(openId);
            orderItem.setUpdateBy(openId);
            orderItem.setId(String.valueOf(System.currentTimeMillis()));
            if (skuBySkuId != null) {
                orderItem.setCategoryId(skuBySkuId.getCategoryPath());
                orderItem.setFlowPrice(skuBySkuId.getPrice());
                orderItem.setGoodsPrice(skuBySkuId.getPrice());
                orderItem.setGoodsId(skuBySkuId.getGoodsId());
                orderItem.setImage(skuBySkuId.getOriginal());
                orderItem.setGoodsName(skuBySkuId.getGoodsName());
                orderItem.setNum(1);
                orderItem.setSkuId(skuId);
                orderItem.setStoreName(skuBySkuId.getStoreName());
                orderItem.setImage(skuBySkuId.getOriginal());
                orderItem.setThumbnail(skuBySkuId.getOriginal());
                totalPrice = totalPrice + skuBySkuId.getPrice();
            }
            orderItem.setSn(orderSn);
            orderItems.add(orderItem);
        }
        orderItemService.saveBatch(orderItems);
        return totalPrice;
    }

    private String createOrder(String openId, String[] skuIds, String orderSn, Double totalPrice) {
        long l = System.currentTimeMillis();

        Order order = new Order();
        order.setOrderStatus(OrderStatusEnum.UNPAID.name());
        order.setDeleteFlag(false);
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        order.setCreateBy(openId);
        order.setUpdateBy(openId);
        order.setId(String.valueOf(l));
        // 物流相关的信息
        MemberAddress memberAddress = memberAddressService.getDefaultMemberAddress(openId);
        if (memberAddress != null) {
            order.setConsigneeAddressIdPath(memberAddress.getConsigneeAddressIdPath());
            order.setConsigneeAddressPath(memberAddress.getConsigneeAddressPath());
            order.setConsigneeDetail(memberAddress.getDetail());
            order.setConsigneeMobile(memberAddress.getMobile());
            order.setConsigneeName(memberAddress.getName());
            order.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
        }

        // 金额相关的信息
        order.setDiscountPrice(new Double(0));
        order.setFlowPrice(totalPrice);
        order.setFreightPrice(new Double(10));
        order.setGoodsNum(skuIds.length);
        order.setGoodsPrice(totalPrice);

        // 会员相关信息
        order.setMemberId(openId);
        Member byMobile = memberService.findByMobile(openId);
        if (byMobile != null && byMobile.getNickName() != null) {
            order.setMemberName(byMobile.getNickName());
        }else {
            order.setMemberName("test");
        }
        order.setOrderType(OrderTypeEnum.NORMAL.name());
        order.setPayStatus(PayStatusEnum.UNPAID.name());
        order.setSn(orderSn);
        log.info(".createOrder memberName:{}", order.getMemberName());
        orderMapper.insert(order);
        return orderSn;
    }
}